Group Shifted Strings

Given a string, we can “shift” each of its letter to its successive letter, for example: “abc” -> “bcd”. We can keep “shifting” which forms the sequence:

  1. "abc" -> "bcd" -> ... -> "xyz"

Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence.

For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"],

A solution is:

  1. [
  2. ["abc","bcd","xyz"],
  3. ["az","ba"],
  4. ["acef"],
  5. ["a","z"]
  6. ]

Solution:

  1. public class Solution {
  2. public List<List<String>> groupStrings(String[] strings) {
  3. List<List<String>> res = new ArrayList<>();
  4. Map<String, List<String>> map = new HashMap<>();
  5. for (int i = 0; i < strings.length; i++) {
  6. String s = strings[i];
  7. String key = hash(s);
  8. List<String> list = map.containsKey(key) ? map.get(key) : new ArrayList<String>();
  9. list.add(s);
  10. map.put(key, list);
  11. }
  12. for (List<String> list : map.values()) {
  13. Collections.sort(list);
  14. res.add(list);
  15. }
  16. return res;
  17. }
  18. String hash(String s) {
  19. String key = "";
  20. for (int i = 1; i < s.length(); i++) {
  21. int diff = (int)(s.charAt(i) - s.charAt(i - 1));
  22. if (diff < 0) diff += 26;
  23. key += String.valueOf(diff);
  24. }
  25. return key;
  26. }
  27. }